<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.ico">
  <link rel="mask-icon" href="/images/favicon.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"daorongxing.gitee.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":"mac"},"back2top":{"enable":true,"sidebar":true,"scrollpercent":true},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":false,"pangu":true,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="JVM内存结构 内存结构基本示意图：  1. 程序计数器1.1 定义行号指示器，字节码解释器运行时通过改变计数器值来选取下一条需要执行的字节码指令。 1.2 特点每条线程都需要有独立的程序计数器，线程私有 唯一一个不会出现OutOfMemoryError情况的内存区域 2. 栈2.1 栈和栈帧 栈：线程运行所需要的内存空间  线程生命周期和栈的生命周期相同 栈的内存空间和线程数呈负相关   栈帧：">
<meta property="og:type" content="article">
<meta property="og:title" content="JVM内存结构">
<meta property="og:url" content="https://daorongxing.gitee.io/post/27692/index.html">
<meta property="og:site_name" content="邢道荣的个人博客">
<meta property="og:description" content="JVM内存结构 内存结构基本示意图：  1. 程序计数器1.1 定义行号指示器，字节码解释器运行时通过改变计数器值来选取下一条需要执行的字节码指令。 1.2 特点每条线程都需要有独立的程序计数器，线程私有 唯一一个不会出现OutOfMemoryError情况的内存区域 2. 栈2.1 栈和栈帧 栈：线程运行所需要的内存空间  线程生命周期和栈的生命周期相同 栈的内存空间和线程数呈负相关   栈帧：">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://daorongxing.gitee.io/images/%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/MemoryStructure.png">
<meta property="og:image" content="https://daorongxing.gitee.io/images/jmap1.png">
<meta property="article:published_time" content="2022-11-24T08:25:39.000Z">
<meta property="article:modified_time" content="2022-11-24T10:37:53.038Z">
<meta property="article:author" content="Daorong Xing">
<meta property="article:tag" content="JVM">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://daorongxing.gitee.io/images/%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84.png">

<link rel="canonical" href="https://daorongxing.gitee.io/post/27692/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>JVM内存结构 | 邢道荣的个人博客</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">邢道荣的个人博客</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://daorongxing.gitee.io/post/27692/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Daorong Xing">
      <meta itemprop="description" content="这是我的个人博客，记录计算机学习之路！">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="邢道荣的个人博客">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          JVM内存结构
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>
              

              <time title="创建时间：2022-11-24 16:25:39 / 修改时间：18:37:53" itemprop="dateCreated datePublished" datetime="2022-11-24T16:25:39+08:00">2022-11-24</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/JVM/" itemprop="url" rel="index"><span itemprop="name">JVM</span></a>
                </span>
            </span>

          <br>
            <span class="post-meta-item" title="本文字数">
              <span class="post-meta-item-icon">
                <i class="far fa-file-word"></i>
              </span>
                <span class="post-meta-item-text">本文字数：</span>
              <span>8.4k</span>
            </span>
            <span class="post-meta-item" title="阅读时长">
              <span class="post-meta-item-icon">
                <i class="far fa-clock"></i>
              </span>
                <span class="post-meta-item-text">阅读时长 &asymp;</span>
              <span>8 分钟</span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="JVM内存结构"><a href="#JVM内存结构" class="headerlink" title="JVM内存结构"></a>JVM内存结构</h1><p><img src="/images/%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84.png"></p>
<p>内存结构基本示意图：</p>
<p><img src="/images/MemoryStructure.png"></p>
<h2 id="1-程序计数器"><a href="#1-程序计数器" class="headerlink" title="1. 程序计数器"></a>1. 程序计数器</h2><h3 id="1-1-定义"><a href="#1-1-定义" class="headerlink" title="1.1 定义"></a>1.1 定义</h3><p>行号指示器，字节码解释器运行时通过改变计数器值来选取下一条需要执行的字节码指令。</p>
<h3 id="1-2-特点"><a href="#1-2-特点" class="headerlink" title="1.2 特点"></a>1.2 特点</h3><p>每条线程都需要有独立的程序计数器，<strong>线程私有</strong></p>
<p><mark>唯一一个</mark>不会出现<font color=red>OutOfMemoryError</font>情况的内存区域</p>
<h2 id="2-栈"><a href="#2-栈" class="headerlink" title="2. 栈"></a>2. 栈</h2><h3 id="2-1-栈和栈帧"><a href="#2-1-栈和栈帧" class="headerlink" title="2.1 栈和栈帧"></a>2.1 栈和栈帧</h3><ul>
<li><p><strong>栈：线程运行所需要的内存空间</strong></p>
<ol>
<li>线程生命周期和栈的生命周期相同</li>
<li>栈的内存空间和线程数呈负相关</li>
</ol>
</li>
<li><p><strong>栈帧：每个方法运行时所需要的内存</strong></p>
<ol>
<li>存储局部变量表，操作数栈，动态连接，方法出口等</li>
<li>生命周期和方法相同，每个方法调用直到执行完毕，就对应着栈帧入栈到出栈的过程。</li>
</ol>
</li>
</ul>
<blockquote>
<p>局部变量表：用于存储方法参数和局部变量等 </p>
</blockquote>
<h3 id="2-2-栈的线程安全"><a href="#2-2-栈的线程安全" class="headerlink" title="2.2 栈的线程安全"></a>2.2 栈的线程安全</h3><p><font size=5 color="red"><strong>！！！方法内的局部变量是否涉及线程安全：</strong></font></p>
<blockquote>
<p>线程安全：保证多个线程同时对某一对象或资源进行操作时不会出错</p>
</blockquote>
<ol>
<li>如果方法内局部变量没有<mark>逃离方法作用范围</mark>，那么他是**<u>线程安全</u>**的:</li>
</ol>
<p>​		没有逃离方法的作用范围，局部变量无逃逸，无法被其他线程访问。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">m1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">    sb.append(<span class="number">1</span>);</span><br><span class="line">    sb.append(<span class="number">2</span>);</span><br><span class="line">    sb.append(<span class="number">3</span>);</span><br><span class="line">    System.out.println(sb.toString());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<ol start="2">
<li><p>如果局部变量引用了对象，并<mark>逃离方法的作用范围</mark>，那么他是**<u>不安全</u>**的:</p>
<p>作为参数传参进入，可以会有被别的对象调用的风险。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">m2</span><span class="params">(StringBuilder sb)</span> &#123;</span><br><span class="line">    sb.append(<span class="number">1</span>);</span><br><span class="line">    sb.append(<span class="number">2</span>);</span><br><span class="line">    sb.append(<span class="number">3</span>);</span><br><span class="line">    System.out.println(sb.toString());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<p>​		存在返回值，有可能被他人调用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> StringBuilder <span class="title function_">m3</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">    sb.append(<span class="number">1</span>);</span><br><span class="line">    sb.append(<span class="number">2</span>);</span><br><span class="line">    sb.append(<span class="number">3</span>);</span><br><span class="line">    <span class="keyword">return</span> sb;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="2-3-栈的有关异常"><a href="#2-3-栈的有关异常" class="headerlink" title="2.3 栈的有关异常"></a>2.3 栈的有关异常</h3><ol>
<li><strong><font color=red>StackOverFlowError</font></strong>: 线程请求的栈深度大于虚拟机所允许的深度</li>
</ol>
<p>​			一般出现原因为<mark>递归</mark>调用<mark>无设置终止条件</mark>或者<mark>终止条件无法达到</mark></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1_2</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> count;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            method1();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Throwable e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            System.out.println(count);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">method1</span><span class="params">()</span> &#123;</span><br><span class="line">        count++;</span><br><span class="line">        method1(); <span class="comment">//递归调用自己，但是没有设置终止条件</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li><font color=red><strong>OutOfMemoryError</strong></font>: 栈无法申请到足够多的内存空间时</li>
</ol>
<p>​			与内存空间有关。</p>
<h2 id="3-本地方法栈"><a href="#3-本地方法栈" class="headerlink" title="3. 本地方法栈"></a>3. 本地方法栈</h2><p>为本地方法运行提供空间的内存空间</p>
<p><code>public native int hashCode();</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">equals</span><span class="params">(Object obj)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> (<span class="built_in">this</span> == obj);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>含有**<u>native关键字</u>**修饰的方法<br>    object: motify, add, hashcode….</p>
<h2 id="4-堆"><a href="#4-堆" class="headerlink" title="4. 堆"></a>4. 堆</h2><h3 id="4-1-定义"><a href="#4-1-定义" class="headerlink" title="4.1 定义"></a>4.1 定义</h3><p>是被所有<mark>线程共享</mark>的一块区域，在<mark>虚拟机启动</mark>的时候自动创建，目的是<mark>存放对象实例(new)</mark>。</p>
<h3 id="4-2-特点"><a href="#4-2-特点" class="headerlink" title="4.2 特点"></a>4.2 特点</h3><ul>
<li>线程共享，需要考虑线程安全的问题</li>
<li>在虚拟机启动的时候自动创建</li>
<li>有垃圾回收机制</li>
</ul>
<h3 id="4-3-堆内存溢出"><a href="#4-3-堆内存溢出" class="headerlink" title="4.3 堆内存溢出"></a>4.3 堆内存溢出</h3><p> <strong>java.lang.OutOfMemoryError:  Java heap space：</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="type">String</span> <span class="variable">a</span> <span class="operator">=</span> <span class="string">&quot;hello&quot;</span>;</span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            list.add(a); <span class="comment">// hello, hellohello, hellohellohellohello ...</span></span><br><span class="line">            a = a + a;  <span class="comment">// hellohellohellohello</span></span><br><span class="line">            i++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125; <span class="keyword">catch</span> (Throwable e) &#123;</span><br><span class="line">        e.printStackTrace();</span><br><span class="line">        System.out.println(i);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="4-4-堆内存诊断"><a href="#4-4-堆内存诊断" class="headerlink" title="4.4 堆内存诊断"></a>4.4 堆内存诊断</h3><ul>
<li><strong>JPS： 查看系统中有哪些java进程</strong></li>
</ul>
<p>直接在<code>Terminal</code>窗口输入jps中可得到下图结果。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//进程编号         //进程名称</span></span><br><span class="line"><span class="number">11936</span>              Jps</span><br><span class="line"><span class="number">13664</span>              Demo1_4</span><br><span class="line"><span class="number">436</span>              </span><br><span class="line"><span class="number">9388</span>              Launcher</span><br></pre></td></tr></table></figure>

<ul>
<li><strong>Jmap：观测指定进程的内存情况</strong></li>
</ul>
<p>用<code> jmap -heap + 进程编号</code>查看当前进程的运行情况</p>
<img src="/images/jmap1.png" style="zoom: 67%;" title="堆配置信息" align="left"/>

<figure class="highlight plaintext"><figcaption><span>Configuration```： 堆配置信息</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">```MaxHeapSize```： 最大堆空间</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;img src=&quot;/images/jmap2.png&quot; style=&quot;zoom:67%;&quot; align=&quot;left&quot;/&gt;</span><br><span class="line"></span><br><span class="line">```Heap Usage```： 堆使用情况</span><br><span class="line"></span><br><span class="line">```used```： 已经使用</span><br><span class="line"></span><br><span class="line">```free```： 未使用</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">- **Jconsole：图形化页面监测工具，可以实现动态的检测**</span><br><span class="line"></span><br><span class="line">&lt;img src=&quot;/images/jconsole.png&quot; style=&quot;zoom:50%;&quot; align=&quot;left&quot; /&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 5. 方法区</span><br><span class="line"></span><br><span class="line">### 5.1 作用</span><br><span class="line"></span><br><span class="line">存储被虚拟机加载的类型信息，常量，静态变量，代码缓存等数据</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 5.2  JVM1.8和1.6不同的组成</span><br><span class="line"></span><br><span class="line">![](/images/MethodArea.png)</span><br><span class="line"></span><br><span class="line">主要变化：实现方式由永久代转变为了元空间，常量池中```StringTable```放到了堆内存中。</span><br><span class="line"></span><br><span class="line">原因：永久代垃圾回收机制为```Full GC```，回收效率低，易导致临时变量占据空间过多，堆内存中垃圾回收机制较永久代灵活</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 5.3 方法区内存溢出</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">```java</span><br><span class="line">    public static void main(String[] args) &#123;</span><br><span class="line">        int j = 0;</span><br><span class="line">        try &#123;</span><br><span class="line">            Demo1_8 test = new Demo1_8();</span><br><span class="line">            for (int i = 0; i &lt; 10000; i++, j++) &#123;</span><br><span class="line">                // ClassWriter 作用是生成类的二进制字节码</span><br><span class="line">                ClassWriter cw = new ClassWriter(0);</span><br><span class="line">                // 版本号， public， 类名, 包名, 父类， 接口</span><br><span class="line">                cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, &quot;Class&quot; + i, null, &quot;java/lang/Object&quot;, null);</span><br><span class="line">                // 返回 byte[]</span><br><span class="line">                byte[] code = cw.toByteArray();</span><br><span class="line">                // 执行了类的加载</span><br><span class="line">                test.defineClass(&quot;Class&quot; + i, code, 0, code.length); // Class 对象</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; finally &#123;</span><br><span class="line">            System.out.println(j);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>1.8 元空间内存溢出</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// java.lang.OutOfMemoryError: Metaspace</span></span><br><span class="line"><span class="comment">// -XX:MaxMetaspaceSize=8m</span></span><br></pre></td></tr></table></figure>



<ul>
<li>1.6 永久代内存溢出</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// java.lang.OutOfMemoryError: PermGen space</span></span><br><span class="line"><span class="comment">// -XX:MaxPermSize=8m</span></span><br></pre></td></tr></table></figure>



<h2 id="6-常量池"><a href="#6-常量池" class="headerlink" title="6. 常量池"></a>6. 常量池</h2><p>作用：用于存储信息，本身时二进制字节码对象，常量池中的信息，都会被加载到运行时常量池中， 这时 a b ab 都是常量池中的符号，还没有变为 java 字符串对象</p>
<p>通过<code>javap -v HelloWorld.class</code>可以获得class二进制字节码文件的基本信息</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line">  <span class="comment">// 基本配置信息</span></span><br><span class="line">  Last modified <span class="number">2022</span>-<span class="number">11</span>-<span class="number">24</span>; size <span class="number">442</span> bytes</span><br><span class="line">  MD5 checksum 103606e24ec918e862312533fda15bbc</span><br><span class="line">  Compiled from <span class="string">&quot;HelloWorld.java&quot;</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">cn</span>.itcast.jvm.t5.HelloWorld</span><br><span class="line">  minor version: <span class="number">0</span></span><br><span class="line">  major version: <span class="number">52</span></span><br><span class="line">  flags: ACC_PUBLIC, ACC_SUPER</span><br><span class="line">      <span class="comment">//常量池</span></span><br><span class="line">Constant pool:</span><br><span class="line">   #<span class="number">1</span> = Methodref          #<span class="number">6.</span>#<span class="number">15</span>         <span class="comment">// java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">   #<span class="number">2</span> = Fieldref           #<span class="number">16.</span>#<span class="number">17</span>        <span class="comment">// java/lang/System.out:Ljava/io/PrintStream;</span></span><br><span class="line">   #<span class="number">3</span> = String             #<span class="number">18</span>            <span class="comment">// hello world</span></span><br><span class="line">   #<span class="number">4</span> = Methodref          #<span class="number">19.</span>#<span class="number">20</span>        <span class="comment">// java/io/PrintStream.println:(Ljava/lang/String;)V</span></span><br><span class="line">   #<span class="number">5</span> = Class              #<span class="number">21</span>            <span class="comment">// cn/itcast/jvm/t5/HelloWorld</span></span><br><span class="line">   #<span class="number">6</span> = Class              #<span class="number">22</span>            <span class="comment">// java/lang/Object</span></span><br><span class="line">   #<span class="number">7</span> = Utf8               &lt;init&gt;</span><br><span class="line">   #<span class="number">8</span> = Utf8               ()V</span><br><span class="line">   #<span class="number">9</span> = Utf8               Code</span><br><span class="line">  #<span class="number">10</span> = Utf8               LineNumberTable</span><br><span class="line">  #<span class="number">11</span> = Utf8               main</span><br><span class="line">  #<span class="number">12</span> = Utf8               ([Ljava/lang/String;)V</span><br><span class="line">  #<span class="number">13</span> = Utf8               SourceFile</span><br><span class="line">  #<span class="number">14</span> = Utf8               HelloWorld.java</span><br><span class="line">  #<span class="number">15</span> = NameAndType        #<span class="number">7</span>:#<span class="number">8</span>          <span class="comment">// &quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">  #<span class="number">16</span> = Class              #<span class="number">23</span>            <span class="comment">// java/lang/System</span></span><br><span class="line">  #<span class="number">17</span> = NameAndType        #<span class="number">24</span>:#<span class="number">25</span>        <span class="comment">// out:Ljava/io/PrintStream;</span></span><br><span class="line">  #<span class="number">18</span> = Utf8               hello world</span><br><span class="line">  #<span class="number">19</span> = Class              #<span class="number">26</span>            <span class="comment">// java/io/PrintStream</span></span><br><span class="line">  #<span class="number">20</span> = NameAndType        #<span class="number">27</span>:#<span class="number">28</span>        <span class="comment">// println:(Ljava/lang/String;)V</span></span><br><span class="line">  #<span class="number">21</span> = Utf8               cn/itcast/jvm/t5/HelloWorld</span><br><span class="line">  #<span class="number">22</span> = Utf8               java/lang/Object</span><br><span class="line">  #<span class="number">23</span> = Utf8               java/lang/System</span><br><span class="line">  #<span class="number">24</span> = Utf8               out</span><br><span class="line">  #<span class="number">25</span> = Utf8               Ljava/io/PrintStream;</span><br><span class="line">  #<span class="number">26</span> = Utf8               java/io/PrintStream</span><br><span class="line">  #<span class="number">27</span> = Utf8               println</span><br><span class="line">  #<span class="number">28</span> = Utf8               (Ljava/lang/String;)V</span><br><span class="line">                             </span><br><span class="line">   <span class="comment">// 类方法定义</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="keyword">public</span> cn.itcast.jvm.t5.HelloWorld();</span><br><span class="line">    descriptor: ()V</span><br><span class="line">    flags: ACC_PUBLIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">1</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: aload_0</span><br><span class="line">         <span class="number">1</span>: invokespecial #<span class="number">1</span>                  <span class="comment">// Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V</span></span><br><span class="line">         <span class="number">4</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">4</span>: <span class="number">0</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(java.lang.String[])</span>;</span><br><span class="line">    descriptor: ([Ljava/lang/String;)V</span><br><span class="line">    flags: ACC_PUBLIC, ACC_STATIC</span><br><span class="line">    Code:</span><br><span class="line">      stack=<span class="number">2</span>, locals=<span class="number">1</span>, args_size=<span class="number">1</span></span><br><span class="line">         <span class="number">0</span>: getstatic     #<span class="number">2</span>                  <span class="comment">// Field java/lang/System.out:Ljava/io/PrintStream;</span></span><br><span class="line">         <span class="number">3</span>: ldc           #<span class="number">3</span>                  <span class="comment">// String hello world</span></span><br><span class="line">         <span class="number">5</span>: invokevirtual #<span class="number">4</span>                  <span class="comment">// Method java/io/PrintStream.println:(Ljava/lang/String;)V</span></span><br><span class="line">         <span class="number">8</span>: <span class="keyword">return</span></span><br><span class="line">      LineNumberTable:</span><br><span class="line">        line <span class="number">6</span>: <span class="number">0</span></span><br><span class="line">        line <span class="number">7</span>: <span class="number">8</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>主要操作流程： 根据指令后面编号去查找相应内容</p>
<h2 id="7-StringTable"><a href="#7-StringTable" class="headerlink" title="7. StringTable"></a>7. StringTable</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s1</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s3</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span> + <span class="string">&quot;b&quot;</span>; <span class="comment">// ab</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s4</span> <span class="operator">=</span> s1 + s2;   <span class="comment">// new String(&quot;ab&quot;)</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s5</span> <span class="operator">=</span> <span class="string">&quot;ab&quot;</span>;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s6</span> <span class="operator">=</span> s4.intern();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 问</span></span><br><span class="line">        System.out.println(s3 == s4); <span class="comment">// false</span></span><br><span class="line">        System.out.println(s3 == s5); <span class="comment">// true</span></span><br><span class="line">        System.out.println(s3 == s6); <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">        <span class="type">String</span> <span class="variable">x2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;c&quot;</span>) + <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;d&quot;</span>); <span class="comment">// new String(&quot;cd&quot;)</span></span><br><span class="line">        x2.intern();</span><br><span class="line">        <span class="type">String</span> <span class="variable">x1</span> <span class="operator">=</span> <span class="string">&quot;cd&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 问，如果调换了【最后两行代码】的位置呢，如果是jdk1.6呢</span></span><br><span class="line">        System.out.println(x1 == x2);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="7-1-常量池与串池之间的关系"><a href="#7-1-常量池与串池之间的关系" class="headerlink" title="7.1 常量池与串池之间的关系"></a>7.1 常量池与串池之间的关系</h3><p>常量池中存储的信息只是作为一个符号，通过方法调用（<code>String a = &quot;a&quot;</code>）或引用的时候才能真正的成为一个对象，而这时候如果串池中没有该对象的时候，将对象放入串池</p>
<p><mark>懒惰性：用到了才会在串池中创建，没有用到不会创建<strong>（延迟加载）</strong></mark></p>
<p>HashCode结构</p>
<h3 id="7-2-字符串拼接"><a href="#7-2-字符串拼接" class="headerlink" title="7.2 字符串拼接"></a>7.2 字符串拼接</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">s1</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">s3</span> <span class="operator">=</span> s1 + s2;</span><br><span class="line"><span class="type">String</span> <span class="variable">s4</span> <span class="operator">=</span> <span class="string">&quot;ab&quot;</span>;</span><br><span class="line"><span class="comment">// new StringBuilder().append(&quot;a&quot;).append(&quot;b&quot;).toString()-&gt; new String(&quot;ab&quot;)</span></span><br><span class="line"><span class="comment">// toString()方法生成了一个新的String对象</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> s3 == s4; <span class="comment">//false</span></span><br></pre></td></tr></table></figure>



<h3 id="7-3-编译期优化"><a href="#7-3-编译期优化" class="headerlink" title="7.3 编译期优化"></a>7.3 编译期优化</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">s1</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> <span class="string">&quot;b&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">s3</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span> + <span class="string">&quot;b&quot;</span>; <span class="comment">//编译期的优化：两个常量之和是确定的</span></span><br><span class="line"><span class="type">String</span> <span class="variable">s4</span> <span class="operator">=</span> <span class="string">&quot;ab&quot;</span>;</span><br><span class="line"><span class="keyword">return</span> s3 == s4 <span class="comment">//true</span></span><br></pre></td></tr></table></figure>



<h3 id="7-4-intern-方法"><a href="#7-4-intern-方法" class="headerlink" title="7.4 intern()方法"></a>7.4 intern()方法</h3><ul>
<li>1.8</li>
</ul>
<p>将字符串对象放入串池，有则不会放入，无则放入后返回</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line"></span><br><span class="line">   </span><br><span class="line">    <span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;a&quot;</span>) + <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 堆  new String(&quot;a&quot;)   new String(&quot;b&quot;) new String(&quot;ab&quot;)</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> s.intern(); <span class="comment">// 将这个字符串对象尝试放入串池，如果有则并不会放入，如果没有则放入串池， 会把串池中的对象返回</span></span><br><span class="line"> 	<span class="type">String</span> <span class="variable">x</span> <span class="operator">=</span> <span class="string">&quot;ab&quot;</span>;</span><br><span class="line">    System.out.println( s2 == x); <span class="comment">//true</span></span><br><span class="line">    System.out.println( s == x ); <span class="comment">//true</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>1.6</li>
</ul>
<p>地址复制后放入串池（和原来的地址不相同）</p>
<p>public static void main(String[] args) {</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;a&quot;</span>) + <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;b&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 堆  new String(&quot;a&quot;)   new String(&quot;b&quot;) new String(&quot;ab&quot;)</span></span><br><span class="line"><span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> s.intern(); <span class="comment">// 将这个字符串对象尝试放入串池，如果有则并不会放入，如果没有则放入串池， 会把串池中的对象返回</span></span><br><span class="line"><span class="type">String</span> <span class="variable">x</span> <span class="operator">=</span> <span class="string">&quot;ab&quot;</span>;</span><br><span class="line">System.out.println( s2 == x); <span class="comment">//true</span></span><br><span class="line">System.out.println( s == x ); <span class="comment">//false   因为s2是复制的，和原来地址并不一样</span></span><br></pre></td></tr></table></figure>
<p>}</p>
<h3 id="7-5-性能调优"><a href="#7-5-性能调优" class="headerlink" title="7.5 性能调优"></a>7.5 性能调优</h3><ul>
<li>调整-XX:StringTableSize&#x3D;桶个数：桶个数多有利于提高效率</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">    <span class="keyword">try</span> (<span class="type">BufferedReader</span> <span class="variable">reader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;linux.words&quot;</span>), <span class="string">&quot;utf-8&quot;</span>))) &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">line</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="type">long</span> <span class="variable">start</span> <span class="operator">=</span> System.nanoTime();</span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            line = reader.readLine();</span><br><span class="line">            <span class="keyword">if</span> (line == <span class="literal">null</span>) &#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            line.intern();</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;cost:&quot;</span> + (System.nanoTime() - start) / <span class="number">1000000</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>考虑串是否入池：重复字符串入池有助于提高效率</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line"></span><br><span class="line">    List&lt;String&gt; address = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">    System.in.read();</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">        <span class="keyword">try</span> (<span class="type">BufferedReader</span> <span class="variable">reader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;linux.words&quot;</span>), <span class="string">&quot;utf-8&quot;</span>))) &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">line</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">            <span class="type">long</span> <span class="variable">start</span> <span class="operator">=</span> System.nanoTime();</span><br><span class="line">            <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">                line = reader.readLine();</span><br><span class="line">                <span class="keyword">if</span>(line == <span class="literal">null</span>) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                address.add(line.intern());</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;cost:&quot;</span> +(System.nanoTime()-start)/<span class="number">1000000</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    System.in.read();</span><br></pre></td></tr></table></figure>

<h2 id="8-直接内存"><a href="#8-直接内存" class="headerlink" title="8. 直接内存"></a>8. 直接内存</h2><h3 id="8-1-作用"><a href="#8-1-作用" class="headerlink" title="8.1 作用"></a>8.1 作用</h3><p>是一种操作系统的内存，可以通过NIO中的directBuffer对象来实现内存调用的效率提高</p>
<p>直接用buffer调用需要通过系统缓冲区和Java缓冲区，而directMomery可以直接访问</p>
<h3 id="8-2-特点"><a href="#8-2-特点" class="headerlink" title="8.2 特点"></a>8.2 特点</h3><ol>
<li>分配回收成本高，读写性能高</li>
<li>和系统内存相关，和java本身堆大小无关</li>
</ol>
<h3 id="8-3-内存释放"><a href="#8-3-内存释放" class="headerlink" title="8.3 内存释放"></a>8.3 内存释放</h3><p>通过unsafe对象对于directMomery对象的调用</p>

    </div>

    
    
    
        

<div>
<ul class="post-copyright">
  <li class="post-copyright-author">
    <strong>本文作者： </strong>Daorong Xing
  </li>
  <li class="post-copyright-link">
    <strong>本文链接：</strong>
    <a href="https://daorongxing.gitee.io/post/27692/" title="JVM内存结构">https://daorongxing.gitee.io/post/27692/</a>
  </li>
  <li class="post-copyright-license">
    <strong>版权声明： </strong>本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" rel="noopener" target="_blank"><i class="fab fa-fw fa-creative-commons"></i>BY-NC-SA</a> 许可协议。转载请注明出处！
  </li>
</ul>
</div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/tags/JVM/" rel="tag"><i class="fa fa-tag"></i> JVM</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/post/32766/" rel="prev" title="数组">
      <i class="fa fa-chevron-left"></i> 数组
    </a></div>
      <div class="post-nav-item">
    <a href="/post/42640/" rel="next" title="JVM概述">
      JVM概述 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84"><span class="nav-text">JVM内存结构</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E7%A8%8B%E5%BA%8F%E8%AE%A1%E6%95%B0%E5%99%A8"><span class="nav-text">1. 程序计数器</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-%E5%AE%9A%E4%B9%89"><span class="nav-text">1.1 定义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-%E7%89%B9%E7%82%B9"><span class="nav-text">1.2 特点</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E6%A0%88"><span class="nav-text">2. 栈</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E6%A0%88%E5%92%8C%E6%A0%88%E5%B8%A7"><span class="nav-text">2.1 栈和栈帧</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E6%A0%88%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8"><span class="nav-text">2.2 栈的线程安全</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-%E6%A0%88%E7%9A%84%E6%9C%89%E5%85%B3%E5%BC%82%E5%B8%B8"><span class="nav-text">2.3 栈的有关异常</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%9C%AC%E5%9C%B0%E6%96%B9%E6%B3%95%E6%A0%88"><span class="nav-text">3. 本地方法栈</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%A0%86"><span class="nav-text">4. 堆</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E5%AE%9A%E4%B9%89"><span class="nav-text">4.1 定义</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E7%89%B9%E7%82%B9"><span class="nav-text">4.2 特点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-%E5%A0%86%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA"><span class="nav-text">4.3 堆内存溢出</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-4-%E5%A0%86%E5%86%85%E5%AD%98%E8%AF%8A%E6%96%AD"><span class="nav-text">4.4 堆内存诊断</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-%E5%B8%B8%E9%87%8F%E6%B1%A0"><span class="nav-text">6. 常量池</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-StringTable"><span class="nav-text">7. StringTable</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#7-1-%E5%B8%B8%E9%87%8F%E6%B1%A0%E4%B8%8E%E4%B8%B2%E6%B1%A0%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB"><span class="nav-text">7.1 常量池与串池之间的关系</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-2-%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8B%BC%E6%8E%A5"><span class="nav-text">7.2 字符串拼接</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-3-%E7%BC%96%E8%AF%91%E6%9C%9F%E4%BC%98%E5%8C%96"><span class="nav-text">7.3 编译期优化</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-4-intern-%E6%96%B9%E6%B3%95"><span class="nav-text">7.4 intern()方法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-5-%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98"><span class="nav-text">7.5 性能调优</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#8-%E7%9B%B4%E6%8E%A5%E5%86%85%E5%AD%98"><span class="nav-text">8. 直接内存</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#8-1-%E4%BD%9C%E7%94%A8"><span class="nav-text">8.1 作用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-2-%E7%89%B9%E7%82%B9"><span class="nav-text">8.2 特点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8-3-%E5%86%85%E5%AD%98%E9%87%8A%E6%94%BE"><span class="nav-text">8.3 内存释放</span></a></li></ol></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Daorong Xing"
      src="/images/avatar.gif">
  <p class="site-author-name" itemprop="name">Daorong Xing</p>
  <div class="site-description" itemprop="description">这是我的个人博客，记录计算机学习之路！</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">10</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">4</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">5</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/yourname" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;yourname" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="/2630168952@qq.com" title="E-Mail → 2630168952@qq.com"><i class="fa fa-envelope fa-fw"></i></a>
      </span>
      <span class="links-of-author-item">
        <a href="/2630168952@qq.com" title="QQ → 2630168952@qq.com"><i class="fa fa-qq fa-fw"></i></a>
      </span>
  </div>



<script type="text/javascript" charset="utf-8" src="/js/tagcloud.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/tagcanvas.js"></script>
<div class="widget-wrap">
    <h3 class="widget-title">标签云</h3>
    <div id="myCanvasContainer" class="widget tagcloud">
        <canvas width="250" height="250" id="resCanvas" style="width=100%">
            <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/JVM/" rel="tag">JVM</a><span class="tag-list-count">4</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Spring/" rel="tag">Spring</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%8C%87%E9%92%88/" rel="tag">指针</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%AE%97%E6%B3%95/" rel="tag">算法</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%BB%93%E6%9E%84%E4%BD%93/" rel="tag">结构体</a><span class="tag-list-count">1</span></li></ul>
        </canvas>
    </div>
</div>


      </div>
        <div class="back-to-top motion-element">
          <i class="fa fa-arrow-up"></i>
          <span>0%</span>
        </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Daorong Xing</span>
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-area"></i>
    </span>
      <span class="post-meta-item-text">站点总字数：</span>
    <span title="站点总字数">91k</span>
</div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  




  
<script src="/js/local-search.js"></script>













  

  

</body>
</html>
